package cn.edu.xust.api.controller;


import cn.edu.xust.Ro.*;
import cn.edu.xust.communication.MyAmmeterReader;
import cn.edu.xust.communication.MyWaterReader;
import cn.edu.xust.communication.model.Result;
import cn.edu.xust.communication.server.CommonOp;
import cn.edu.xust.configuration.exception.Default200Exception;
import cn.edu.xust.configuration.exception.ErrorConstant;
import cn.edu.xust.entity.*;
import cn.edu.xust.service.*;
import cn.edu.xust.util.GenUtils;
import cn.edu.xust.util.IpUtil;
import cn.edu.xust.util.JWTUtil;
import cn.edu.xust.util.R;
import com.alibaba.fastjson.JSONObject;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.authz.annotation.Logical;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 新后台用
 */
@Slf4j
@RestController()
@CrossOrigin
@RequestMapping("/api/dev")
public class ApidevController {


    @Autowired
    private DeviceService deviceService;
    @Autowired
    private GatewayService gatewayService;
    @Autowired
    private ElecdataService elecdatas;
    @Autowired
    private WtdataService wtdataService;
    @Autowired
    private HotelService hotelService;
    @Autowired
    private DeviceRegisterLogService deviceRegisterLogService;

    /**
     * 酒店号房间号 查询电表号
     *
     * @param jsonObject
     * @return
     */
    @ResponseBody
    @RequestMapping(value = "/devicelist")
    public R devicelist(@RequestBody JSONObject jsonObject) {
        String hotelid = jsonObject.getString("hotelid");
        String roomname = jsonObject.getString("roomname");

        List<DeviceEntity> deviceEntities = deviceService.getByHotelRoom(hotelid, roomname);

        ArrayList<DeviceRo> deviceEntities1 = new ArrayList<>();
        for (DeviceEntity d : deviceEntities) {
            DeviceRo deviceRo = new DeviceRo();
            deviceRo.setHotelid(String.valueOf(d.getHotelid()));
            deviceRo.setRoomname(d.getRoomname());
            deviceRo.setDeviceid(d.getName());
            deviceRo.setDevicename(d.getNickname());
            deviceEntities1.add(deviceRo);
        }
        return R.ok().put("data", deviceEntities1);
    }


    /**
     * 酒店号 房间号 查询 及时电表信息
     *
     * @param jsonObject
     * @return
     * @throws Default200Exception
     */
    @ResponseBody
    @RequestMapping(value = "/ele/data")
    public R getdata(@RequestBody JSONObject jsonObject) throws Default200Exception {

        //取出数据
        String hotelid = jsonObject.getString("hotelid");
        String roomname = jsonObject.getString("roomname");

        //规定 ： 一个房间只有一个电表，1个或两个水表，热水和冷水   ele   coldwt  hotwt
        List<DeviceEntity> deviceEntities = deviceService.getByHotelRoomAngType(hotelid, roomname, "ele");
        if (deviceEntities.size() != 1) {
            log.info("酒店号:{},房间号:{},他的电表数量异常:{}", hotelid, roomname, deviceEntities.size());
            throw new Default200Exception(ErrorConstant.num_err, ":" + deviceEntities.size() + "台");
        }
        //拿到电表
        DeviceEntity deviceEntity = deviceEntities.get(0);

        //拿到网关
        GatewayEntity gat = gatewayService.getById(deviceEntity.getGatewayid());
        if (gat == null) {
            log.info("配置的网关号不存在:{}", deviceEntity.getGatewayid());
            throw new Default200Exception(ErrorConstant.gateway_not_exsit);
        }

        //拿到ip
        String ip = gat.getIp();
        MyAmmeterReader reader = new MyAmmeterReader(ip, deviceEntity.getName());
        //查询电表
        ElecdataEntity elecdataEntity = reader.readAll(deviceEntity);
        //电量不是空就记录到数据库
        if (StringUtils.isNotEmpty(elecdataEntity.getElecwattage()) && !elecdataEntity.getElecwattage().equals("null")) {
            elecdatas.save(elecdataEntity);
        }
        return R.ok().put("data", elecdataEntity);

    }


    /**
     * 酒店号 房间号 控制 开关电表
     * status on off
     *
     * @return
     * @throws Default200Exception
     */
    @ResponseBody
    @RequestMapping(value = "/ele/control")
    @RequiresPermissions(value = {"28"}, logical = Logical.OR)
    public R operation(@RequestBody JSONObject jsonObject, HttpServletRequest httpServletRequest) throws Default200Exception {


        //取出数据
        String hotelid = jsonObject.getString("hotelid");
        String roomname = jsonObject.getString("roomname");
        String status = jsonObject.getString("status");

        //规定 ： 一个房间只有一个电表，1个或两个水表，热水和冷水   ele   coldwt  hotwt
        List<DeviceEntity> deviceEntities = deviceService.getByHotelRoomAngType(hotelid, roomname, "ele");
        if (deviceEntities.size() != 1) {
            log.info("酒店号:{},房间号:{},他的电表数量异常:{}", hotelid, roomname, deviceEntities.size());
            throw new Default200Exception(ErrorConstant.num_err, ":" + deviceEntities.size() + "台");
        }
        //拿到电表
        DeviceEntity deviceEntity = deviceEntities.get(0);

        //拿到网关
        GatewayEntity gat = gatewayService.getById(deviceEntity.getGatewayid());
        if (gat == null) {
            log.info("配置的网关号不存在:{}", deviceEntity.getGatewayid());
            throw new Default200Exception(ErrorConstant.gateway_not_exsit);
        }

        //拿到ip
        String ip = gat.getIp();
        String cmd = GenUtils.genEleControlCmd(deviceEntity, status);
        log.info("生成指令:{}", cmd);
        Result result = CommonOp.writeCommand(ip, cmd, UUID.randomUUID().toString());
        String message = result.getMessage();
        //记录于日志
        DeviceRegisterLogEntity deviceRegisterLogEntity = new DeviceRegisterLogEntity();
        deviceRegisterLogEntity.setMac(deviceEntity.getName());
        deviceRegisterLogEntity.setHotelid(String.valueOf(deviceEntity.getHotelid()));
        deviceRegisterLogEntity.setRoomid(deviceEntity.getRoomname());
        deviceRegisterLogEntity.setType("电表控制");
        deviceRegisterLogEntity.setCtime(new Date());
        deviceRegisterLogEntity.setNote(status);
        String ipAddr = IpUtil.getIpAddr(httpServletRequest);
        String location = IpUtil.getLocationByIp(ipAddr);
        deviceRegisterLogEntity.setIp(ipAddr);
        deviceRegisterLogEntity.setIplocation(location);
        String token = httpServletRequest.getHeader("authorization");
        String rjwt = token.replace("Bearer ", "");
        String username1 = JWTUtil.getUsername(rjwt);
        deviceRegisterLogEntity.setDoname(username1);
        deviceRegisterLogEntity.setCmd(cmd);
        deviceRegisterLogEntity.setResult("fail");
        if (message.startsWith("FEFEFE")) {
            deviceRegisterLogEntity.setResult("success");
            deviceRegisterLogService.save(deviceRegisterLogEntity);
            return R.ok();
        }
        deviceRegisterLogService.save(deviceRegisterLogEntity);
        return R.error(message);
    }


    /**
     * 酒店号 房间号 热水冷水 获取及时水表信息
     *
     * @param jsonObject
     * @return
     * @throws Default200Exception
     */
    @ResponseBody
    @RequestMapping(value = "/wt/data")
    public R getwtdata(@RequestBody JSONObject jsonObject) throws Default200Exception {

        //取出数据
        String hotelid = jsonObject.getString("hotelid");
        String roomname = jsonObject.getString("roomname");
        String type = jsonObject.getString("type");

        //规定 ： 一个房间只有一个电表，1个或两个水表，热水和冷水   ele   coldwt  hotwt
        List<DeviceEntity> deviceEntities = deviceService.getByHotelRoomAngType(hotelid, roomname, type);
        if (deviceEntities.size() != 1) {
            log.info("酒店号:{},房间号:{},他的水表数量异常:{}", hotelid, roomname, deviceEntities.size());
            throw new Default200Exception(ErrorConstant.num_err, ":" + deviceEntities.size() + "台");
        }
        //拿到水表
        DeviceEntity deviceEntity = deviceEntities.get(0);

        //拿到网关
        GatewayEntity gat = gatewayService.getById(deviceEntity.getGatewayid());
        if (gat == null) {
            log.info("配置的网关号不存在:{}", deviceEntity.getGatewayid());
            throw new Default200Exception(ErrorConstant.gateway_not_exsit);
        }

        //拿到ip
        String ip = gat.getIp();
        MyWaterReader reader = new MyWaterReader(deviceEntity, ip);
        Result result = reader.readAll();


        //解析数据出来 并持久化到数据库中
        WtdataEntity wtdataEntity = deviceService.parsePersistwt(result.getMessage(), "manual-dev");
        return R.ok().put("data", wtdataEntity);
    }


    /**
     * appi(酒店号) 指定日期 获取历史水表信息
     *
     * @param jsonObject
     * @return
     * @throws Default200Exception
     */
    @ResponseBody
    @RequestMapping(value = "/wt/databytime")
    public R wtdatabytime(@RequestParam(value = "appId") String appId, @RequestBody JSONObject jsonObject) throws Default200Exception {

        String date = jsonObject.getString("date");
        if (date == null) {
            throw new Default200Exception(ErrorConstant.date_need);

        }
        HotelEntity hotelEntity = hotelService.getByAppid(appId);
        if (hotelEntity == null) {
            throw new Default200Exception(ErrorConstant.hotel_not_found);
        }

        Integer hotelid = hotelEntity.getHotelId();
        List<DeviceEntity> devices = deviceService.getByHotelAndClassify(String.valueOf(hotelid), "wt");

        List<String> deivcenamelist = devices.stream().map(DeviceEntity::getName).collect(Collectors.toList());
        List<WtdataEntity> datas = wtdataService.getByDeviceNameAndTimetag(deivcenamelist, date);
        Map<String, WtdataEntity> datasmap = new HashMap<>();
        for (WtdataEntity wtdata : datas) {
            datasmap.put(wtdata.getDevicename(), wtdata);
        }

        ArrayList<WtRo2> wtRo2s = new ArrayList<>();
        for (DeviceEntity deviceEntity : devices) {
            WtRo2 wtRO = new WtRo2();
            String devicename = deviceEntity.getName();
            WtdataEntity data = datasmap.get(devicename);
            wtRO.setMac(devicename);
            wtRO.setHotcold(deviceEntity.getType().equals("coldwt") ? "冷水表" : "热水表");
            wtRO.setRoomid(deviceEntity.getRoomname());
            wtRO.setHotelid(String.valueOf(deviceEntity.getHotelid()));
            if (data == null) {
                log.info("没有查到{}:{}的水表数据", date, devicename);
                log.info("向上查询6小时内的最新数据");
                WtdataEntity wtdataEntity = wtdataService.searchNewstInHourtime(date, 6, devicename);
                if (wtdataEntity == null) {
                    WtdataEntity wtdataEntity1 = new WtdataEntity();
//                    wtdataEntity1.setCurrentcumulativeflow("0");
//                    wtdataEntity1.setAccumulatedtrafficday("0");
                    wtRO.setNote("noData");
                    data = wtdataEntity1;
                } else {
                    data = wtdataEntity;
                    wtRO.setNote("timeChanged");
                }
            }
            wtRO.setCurrentCumulativeflow(data.getCurrentcumulativeflow());
            wtRO.setAccumulatedTrafficDay(data.getAccumulatedtrafficday());
            wtRO.setLogtime(data.getCtime());
            wtRo2s.add(wtRO);
        }
        wtRo2s.sort(Comparator.comparing(WtRo2::getRoomid));
        return R.ok().put("data", wtRo2s);
    }


    /**
     * appi(酒店号) 指定日期 获取历史电表信息
     *
     * @param jsonObject
     * @return
     * @throws Default200Exception
     */
    @ResponseBody
    @RequestMapping(value = "/ele/databytime")
    public R eledatabytime(@RequestParam(value = "appId") String appId, @RequestBody JSONObject jsonObject) throws Default200Exception {

        String date = jsonObject.getString("date");
        if (date == null) {
            throw new Default200Exception(ErrorConstant.date_need);
        }
        HotelEntity hotelEntity = hotelService.getByAppid(appId);
        if (hotelEntity == null) {
            throw new Default200Exception(ErrorConstant.hotel_not_found);
        }

        Integer hotelid = hotelEntity.getHotelId();
        List<DeviceEntity> devices = deviceService.getByHotelAndClassify(String.valueOf(hotelid), "ele");

        List<String> deivcenamelist = devices.stream().map(DeviceEntity::getName).collect(Collectors.toList());
        List<ElecdataEntity> datas = elecdatas.getByDeviceNameAndTimetag(deivcenamelist, date);
        Map<String, ElecdataEntity> datasmap = new HashMap<>();
        for (ElecdataEntity eledata : datas) {
            datasmap.put(eledata.getDevicename(), eledata);
        }

        ArrayList<EleRo2> eleRo2s = new ArrayList<>();
        for (DeviceEntity deviceEntity : devices) {
            EleRo2 eleRO = new EleRo2();
            String devicename = deviceEntity.getName();
            ElecdataEntity data = datasmap.get(devicename);
            eleRO.setMac(devicename);
            eleRO.setRoomid(deviceEntity.getRoomname());
            eleRO.setHotelid(String.valueOf(deviceEntity.getHotelid()));
            if (data == null) {
                log.info("没有查到{}:{}的电表数据", date, devicename);
                log.info("向上查询6小时内的最新数据");
                ElecdataEntity elecdataEntity = elecdatas.searchNewstInHourtime(date, 6, devicename);
                if (elecdataEntity == null) {
                    ElecdataEntity eledataEntity1 = new ElecdataEntity();
                    eleRO.setVoltage("0");
                    eleRO.setEleccurrent("0");
                    eleRO.setElecwattage("0");
                    eleRO.setState("off");
                    eleRO.setNote("noData");
                    data = eledataEntity1;
                } else {
                    data = elecdataEntity;
                    eleRO.setNote("timeChanged");
                }
            }
            eleRO.setVoltage(data.getVoltage());
            eleRO.setEleccurrent(data.getEleccurrent());
            eleRO.setElecwattage(data.getElecwattage());
            eleRO.setState(data.getState());
            eleRO.setLogtime(data.getCtime());
            eleRo2s.add(eleRO);
        }
        eleRo2s.sort(Comparator.comparing(EleRo2::getRoomid));
        return R.ok().put("data", eleRo2s);
    }


    /**
     * 酒店号 房间号 指定日期 获取冷热水表信息
     *
     * @param jsonObject
     * @return
     * @throws Default200Exception
     */
    @ResponseBody
    @RequestMapping(value = "/wt/databytimehr")
    public R wtdatabytimehr(@RequestBody JSONObject jsonObject) throws Default200Exception {

        String date = jsonObject.getString("date");
        String hotelid = jsonObject.getString("hotelid");
        String roomid = jsonObject.getString("roomid");
        if (date == null) {
            throw new Default200Exception(ErrorConstant.date_need);
        }
        HotelEntity hotelEntity = hotelService.getById(hotelid);
        if (hotelEntity == null) {
            throw new Default200Exception(ErrorConstant.hotel_not_found);
        }

        DeviceEntity coldwt = deviceService.getByHRType(hotelid, roomid, "coldwt");
        DeviceEntity hotwt = deviceService.getByHRType(hotelid, roomid, "hotwt");

        List<DeviceEntity> devices = new ArrayList<>();
        if (coldwt != null) {
            devices.add(coldwt);
        }
        if (hotwt != null) {
            devices.add(hotwt);
        }
        List<String> deivcenamelist = devices.stream().map(DeviceEntity::getName).collect(Collectors.toList());
        List<WtdataEntity> datas = wtdataService.getByDeviceNameAndTimetag(deivcenamelist, date);
        Map<String, WtdataEntity> datasmap = new HashMap<>();
        for (WtdataEntity wtdata : datas) {
            datasmap.put(wtdata.getDevicename(), wtdata);
        }

        ArrayList<WtRo2> wtRo2s = new ArrayList<>();
        for (DeviceEntity deviceEntity : devices) {
            WtRo2 wtRO = new WtRo2();
            String devicename = deviceEntity.getName();
            WtdataEntity data = datasmap.get(devicename);
            wtRO.setMac(devicename);
            wtRO.setHotcold(deviceEntity.getType().equals("coldwt") ? "冷水表" : "热水表");
            wtRO.setRoomid(deviceEntity.getRoomname());
            wtRO.setHotelid(String.valueOf(deviceEntity.getHotelid()));
            if (data == null) {
                log.info("没有查到{}:{}的水表数据", date, devicename);
                log.info("向上查询6小时内的最新数据");
                WtdataEntity wtdataEntity = wtdataService.searchNewstInHourtime(date, 6, devicename);
                if (wtdataEntity == null) {
                    WtdataEntity wtdataEntity1 = new WtdataEntity();
//                    wtdataEntity1.setCurrentcumulativeflow("0");
//                    wtdataEntity1.setAccumulatedtrafficday("0");
                    wtRO.setNote("noData");
                    data = wtdataEntity1;
                } else {
                    data = wtdataEntity;
                    wtRO.setNote("timeChanged");
                }
            }
            wtRO.setCurrentCumulativeflow(data.getCurrentcumulativeflow());
            wtRO.setAccumulatedTrafficDay(data.getAccumulatedtrafficday());
            wtRO.setLogtime(data.getCtime());
            wtRo2s.add(wtRO);
        }
        wtRo2s.sort(Comparator.comparing(WtRo2::getRoomid));
        return R.ok().put("data", wtRo2s);
    }

    /**
     * 酒店号 房间号 指定日期  获取指定日期水表信息-分酒店房间
     *
     * @param jsonObject
     * @return
     * @throws Default200Exception
     */
    @ResponseBody
    @RequestMapping(value = "/wt/databytimehr2")
    public R wtdatabytimehr2(@RequestBody JSONObject jsonObject) throws Default200Exception {

        String date = jsonObject.getString("date");
        String hotelid = jsonObject.getString("hotelid");
        String roomid = jsonObject.getString("roomid");
        String type = jsonObject.getString("type");
        if (date == null) {
            throw new Default200Exception(ErrorConstant.date_need);
        }
        HotelEntity hotelEntity = hotelService.getById(hotelid);
        if (hotelEntity == null) {
            throw new Default200Exception(ErrorConstant.hotel_not_found);
        }

        DeviceEntity coldwt = deviceService.getByHRType(hotelid, roomid, type);

        List<DeviceEntity> devices = new ArrayList<>();
        if (coldwt != null) {
            devices.add(coldwt);
        }

        List<String> deivcenamelist = devices.stream().map(DeviceEntity::getName).collect(Collectors.toList());
        List<WtdataEntity> datas = wtdataService.getByDeviceNameAndTimetag(deivcenamelist, date);
        Map<String, WtdataEntity> datasmap = new HashMap<>();
        for (WtdataEntity wtdata : datas) {
            datasmap.put(wtdata.getDevicename(), wtdata);
        }

        ArrayList<WtRo2> wtRo2s = new ArrayList<>();
        for (DeviceEntity deviceEntity : devices) {
            WtRo2 wtRO = new WtRo2();
            String devicename = deviceEntity.getName();
            WtdataEntity data = datasmap.get(devicename);
            wtRO.setMac(devicename);
            wtRO.setHotcold(deviceEntity.getType().equals("coldwt") ? "冷水表" : "热水表");
            wtRO.setRoomid(deviceEntity.getRoomname());
            wtRO.setHotelid(String.valueOf(deviceEntity.getHotelid()));
            if (data == null) {
                log.info("没有查到{}:{}的水表数据", date, devicename);
                log.info("向上查询6小时内的最新数据");
                WtdataEntity wtdataEntity = wtdataService.searchNewstInHourtime(date, 6, devicename);
                if (wtdataEntity == null) {
                    WtdataEntity wtdataEntity1 = new WtdataEntity();
//                    wtdataEntity1.setCurrentcumulativeflow("0");
//                    wtdataEntity1.setAccumulatedtrafficday("0");
                    wtRO.setNote("noData");
                    data = wtdataEntity1;
                } else {
                    data = wtdataEntity;
                    wtRO.setNote("timeChanged");
                }
            }
            wtRO.setCurrentCumulativeflow(data.getCurrentcumulativeflow());
            wtRO.setAccumulatedTrafficDay(data.getAccumulatedtrafficday());
            wtRO.setLogtime(data.getCtime());
            wtRo2s.add(wtRO);
        }
        wtRo2s.sort(Comparator.comparing(WtRo2::getRoomid));
        return R.ok().put("data", wtRo2s);
    }

    /**
     * 指定日期 电表 某个房间
     *
     * @param jsonObject
     * @return
     * @throws Default200Exception
     */
    @ResponseBody
    @RequestMapping(value = "/ele/databytimehr")
    public R eledatabytimehr(@RequestBody JSONObject jsonObject) throws Default200Exception {

        String date = jsonObject.getString("date");
        String hotelid = jsonObject.getString("hotelid");
        String roomid = jsonObject.getString("roomid");
        if (date == null) {
            throw new Default200Exception(ErrorConstant.date_need);
        }

        DeviceEntity ele = deviceService.getByHRType(hotelid, roomid, "ele");
        if (ele == null) {
            throw new Default200Exception(ErrorConstant.room_device_num_zero);
        }
        List<DeviceEntity> devices = new ArrayList<>();
        devices.add(ele);

        List<String> deivcenamelist = devices.stream().map(DeviceEntity::getName).collect(Collectors.toList());
        List<ElecdataEntity> datas = elecdatas.getByDeviceNameAndTimetag(deivcenamelist, date);
        Map<String, ElecdataEntity> datasmap = new HashMap<>();
        for (ElecdataEntity eledata : datas) {
            datasmap.put(eledata.getDevicename(), eledata);
        }

        ArrayList<EleRo2> eleRo2s = new ArrayList<>();
        //这里大意了，以为是一个房间可以有两个电表 其实本来不会用到for循环
        for (DeviceEntity deviceEntity : devices) {
            EleRo2 eleRO = new EleRo2();
            String devicename = deviceEntity.getName();
            ElecdataEntity data = datasmap.get(devicename);
            eleRO.setMac(devicename);
            eleRO.setRoomid(deviceEntity.getRoomname());
            eleRO.setHotelid(String.valueOf(deviceEntity.getHotelid()));
            if (data == null) {
                log.info("没有查到{}:{}的电表数据", date, devicename);
                log.info("向上查询6小时内的最新数据");
                ElecdataEntity elecdataEntity = elecdatas.searchNewstInHourtime(date, 6, devicename);
                //如果一点数据都没有
                if (elecdataEntity == null) {
                    ElecdataEntity eledataEntity1 = new ElecdataEntity();
                    eleRO.setVoltage("0");
                    eleRO.setEleccurrent("0");
                    eleRO.setElecwattage("0");
                    eleRO.setState("off");
                    eleRO.setNote("noData");
                    data = eledataEntity1;
                } else {
                    data = elecdataEntity;
                    eleRO.setNote("timeChanged");
                }
            }
            eleRO.setVoltage(data.getVoltage());
            eleRO.setEleccurrent(data.getEleccurrent());
            eleRO.setElecwattage(data.getElecwattage());
            eleRO.setState(data.getState());
            eleRO.setLogtime(data.getCtime());
            eleRo2s.add(eleRO);
        }
        eleRo2s.sort(Comparator.comparing(EleRo2::getRoomid));
        return R.ok().put("data", eleRo2s);
    }


    /**
     * 获取 指定日期 批量 水表
     *
     * @param jsonObject
     * @return
     * @throws Default200Exception
     */
    @ResponseBody
    @RequestMapping(value = "/wt/databytimehotel")
    public R wtdatabytimehotel(@RequestBody JSONObject jsonObject) throws Default200Exception {

        String date = jsonObject.getString("date");
        String hotelid = jsonObject.getString("hotelid");
        if (date == null) {
            throw new Default200Exception(ErrorConstant.date_need);
        }
        HotelEntity hotelEntity = hotelService.getById(hotelid);
        if (hotelEntity == null) {
            throw new Default200Exception(ErrorConstant.hotel_not_found);
        }

        List<MulHotelWtRo> coldwt = wtdataService.getByHType(hotelid, "coldwt", date);
        List<MulHotelWtRo> hotwt = wtdataService.getByHType(hotelid, "hotwt", date);

        JSONObject jsonObject1 = new JSONObject();
        jsonObject1.put("coldwt", coldwt);
        jsonObject1.put("hotwt", hotwt);
        return R.ok().put("data", jsonObject1);
    }


    /**
     * 获取 指定日期 批量 电表
     *
     * @param jsonObject
     * @return
     * @throws Default200Exception
     */
    @ResponseBody
    @RequestMapping(value = "/ele/databytimehotel")
    public R eledatabytimehotel(@RequestBody JSONObject jsonObject) throws Default200Exception {

        String date = jsonObject.getString("date");
        String hotelid = jsonObject.getString("hotelid");
        if (date == null) {
            throw new Default200Exception(ErrorConstant.date_need);
        }
        List<MulHotelEleRo> ele = elecdatas.getByHType(hotelid, "ele", date);
        return R.ok().put("data", ele);
    }


    /**
     * 电表 冷水 热水 日期范围 使用情况图表
     *
     * @param jsonObject
     * @return
     * @throws Default200Exception
     */
    @ResponseBody
    @RequestMapping(value = "/ele/timerange")
    public R eletimerange(@RequestBody JSONObject jsonObject) throws Default200Exception {

        String start = jsonObject.getString("start") + " 00:00:00";
        String end = jsonObject.getString("end") + " 23:59:59";
        String hotelid = jsonObject.getString("hotelid");
        String roomname = jsonObject.getString("roomname");


        List<DeviceEntity> devices = deviceService.getByHotelRoom(hotelid, roomname);
        List<PieData> elepie = new ArrayList<>();
        List<PieData> hotpie = new ArrayList<>();
        List<PieData> coldpie = new ArrayList<>();


        //拿到电表
        List<DeviceEntity> ele1 = devices.stream().filter(e -> e.getType().equals("ele")).collect(Collectors.toList());
        if (ele1.size() == 1) {
            DeviceEntity ele = ele1.get(0);
            elepie = elecdatas.getByDay(ele.getName(), start, end);
        }

        //拿到水表
        List<DeviceEntity> hotwt1 = devices.stream().filter(e -> e.getType().equals("hotwt")).collect(Collectors.toList());
        if (hotwt1.size() == 1) {
            DeviceEntity hotwt = hotwt1.get(0);
            hotpie = wtdataService.getByDay(hotwt.getName(), start, end);

        }
        List<DeviceEntity> coldwt1 = devices.stream().filter(e -> e.getType().equals("coldwt")).collect(Collectors.toList());
        if (coldwt1.size() == 1) {
            DeviceEntity coldwt = coldwt1.get(0);
            coldpie = wtdataService.getByDay(coldwt.getName(), start, end);

        }


        JSONObject jsonObject1 = new JSONObject();
        jsonObject1.put("elepie", elepie);
        jsonObject1.put("coldpie", coldpie);
        jsonObject1.put("hotpie", hotpie);
        return R.ok().put("data", jsonObject1);
    }


    /**
     * 网关状态
     *
     * @param jsonObject
     * @return
     * @throws Default200Exception
     */
    @ResponseBody
    @RequestMapping(value = "/gateways")
    public R gateways(@RequestBody JSONObject jsonObject) throws Default200Exception {

        String hotelid = jsonObject.getString("hotelid");
        List<GatewayEntity> gatewayEntities = gatewayService.getByHotel(hotelid);

        List<Integer> gids = gatewayEntities.stream().map(GatewayEntity::getId).collect(Collectors.toList());
        if(gids.size()==0){
            throw new Default200Exception(ErrorConstant.gateway_zero);
        }
        List<DeviceEntity> deviceEntities = deviceService.getByGatewayids(gids);

        // 创建一个Map用于存储结果
        Map<Integer, Integer> resultMap = new HashMap<>();

        // 遍历deviceEntities列表
        for (DeviceEntity deviceEntity : deviceEntities) {
            // 获取getgeatwayid
            Integer gatewayid = deviceEntity.getGatewayid();
            // 如果resultMap中已经有这个getgeatwayid，更新其数量
            if (resultMap.containsKey(gatewayid)) {
                resultMap.put(gatewayid, resultMap.get(gatewayid) + 1);
            } else {
                // 否则，将新的getgeatwayid添加到resultMap中，数量为1
                resultMap.put(gatewayid, 1);
            }
        }

        for (GatewayEntity gatewayEntity : gatewayEntities) {
            gatewayEntity.setIp(gatewayEntity.getIp().isEmpty() || gatewayEntity.getIp().equals("OFFLINE") ? "0" : "1");
            gatewayEntity.setRegisttxt(String.valueOf(resultMap.get(gatewayEntity.getId())==null?0:resultMap.get(gatewayEntity.getId())));
        }


        return R.ok().put("data", gatewayEntities);
    }

    //获取某个酒店的房间列表
    @ResponseBody
    @RequestMapping(value = "/getrooms")
    public R getrooms(@RequestBody JSONObject jsonObject) throws Default200Exception {

        String hotelid = jsonObject.getString("hotelid");

        List<DeviceEntity> devices = deviceService.getByHotel(hotelid);

        //房间号-该房间的设备
        Map<String, List<DeviceEntity>> groupedDevices = devices.stream()
                .collect(Collectors.groupingBy(DeviceEntity::getRoomname));

        List<RoomDeviceInfo> sortedRoomDeviceInfos = groupedDevices.entrySet().stream()
                .map(entry -> {
                    List<DeviceEntity> sortedDeviceEntities = entry.getValue().stream()
                            //按电表 冷水表 热水表 其他 排序
                            .sorted(Comparator.comparing(device -> {
                                switch (device.getType()) {
                                    case "ele":
                                        return 1;
                                    case "coldwt":
                                        return 2;
                                    case "hotwt":
                                        return 3;
                                    default:
                                        return Integer.MAX_VALUE;
                                }
                            }))
                            .collect(Collectors.toList());
                    return new RoomDeviceInfo(entry.getKey(), sortedDeviceEntities);
                })
                //按房间号排序
                .sorted(Comparator.comparing(RoomDeviceInfo::getRoomname))
                .collect(Collectors.toList());
        return R.ok().put("data", sortedRoomDeviceInfos);
    }


    @Data
    @AllArgsConstructor
    private static class RoomDeviceInfo {
        String roomname;
        List<DeviceEntity> info;
    }


    //获取某个酒店的设备列表
    @ResponseBody
    @RequestMapping(value = "/getmacs")
    public R getmacs(@RequestBody JSONObject jsonObject) {
        String hotelid = jsonObject.getString("hotelid");
        String roomname = jsonObject.getString("roomname");
        String mac = jsonObject.getString("mac");
        List<String> type = (List<String>) jsonObject.get("type");
        List<DeviceEntity> devices = deviceService.getByHotel(hotelid, roomname, mac, type);
        //新增两个字段  today  now


        devices.sort(new DeviceComparator());
        return R.ok().put("data", devices);
    }


    //添加设备
    @RequiresPermissions(value = {"25"}, logical = Logical.OR)
    @ResponseBody
    @RequestMapping(value = "/addmac")
    public R addmac(@RequestBody JSONObject jsonObject) throws Default200Exception {
        String hotelid = jsonObject.getString("hotelid");
        String roomname = jsonObject.getString("roomname");
        String mac = jsonObject.getString("mac");
        String type = jsonObject.getString("type");
        String gatewayid = jsonObject.getString("gatewayid");
        String note = jsonObject.getString("note");
        String model = jsonObject.getString("model");

        HashMap<String, String> map = new HashMap<>();
        map.put("电表", "ele");
        map.put("冷水表", "coldwt");
        map.put("热水表", "hotwt");


        HashMap<String, String> map2 = new HashMap<>();
        map2.put("电表", "ele");
        map2.put("冷水表", "wt");
        map2.put("热水表", "wt");

        DeviceEntity deviceEntity = deviceService.getByHotelRoomAngNickName(hotelid, roomname, type);
        if (deviceEntity != null) {
            throw new Default200Exception(ErrorConstant.room_have_device);
        }
        DeviceEntity deviceEntity2 = deviceService.getByName(mac);
        if (deviceEntity2 != null) {
            throw new Default200Exception(ErrorConstant.macid_alreadyhave);
        }

        DeviceEntity deviceEntity1 = new DeviceEntity();
        deviceEntity1.setName(mac);
        deviceEntity1.setNickname(type);
        deviceEntity1.setType(map.get(type));
        deviceEntity1.setGatewayid(Integer.valueOf(gatewayid));
        deviceEntity1.setNote(note);
        deviceEntity1.setModel(model);
        deviceEntity1.setCtime(new Date());
        deviceEntity1.setSecr("电表".equals(type) ? "35 33 33 33" : "");
        deviceEntity1.setOpcode("电表".equals(type) ? "36 33 33 33" : "");
        deviceEntity1.setHotelid(Integer.valueOf(hotelid));
        deviceEntity1.setRoomname(roomname);
        deviceEntity1.setClassify(map2.get(type));

        deviceService.save(deviceEntity1);

        //记录在log表里
        DeviceRegisterLogEntity deviceRegisterLogEntity = new DeviceRegisterLogEntity();
        deviceRegisterLogEntity.setMac(mac);
        deviceRegisterLogEntity.setHotelid(hotelid);
        deviceRegisterLogEntity.setRoomid(roomname);
        deviceRegisterLogEntity.setType(type);
        deviceRegisterLogEntity.setCtime(new Date());
        deviceRegisterLogEntity.setNote("添加");
        deviceRegisterLogService.save(deviceRegisterLogEntity);

        return R.ok();
    }


    //删除设备
    @ResponseBody
    @RequiresPermissions(value = {"27"}, logical = Logical.OR)
    @RequestMapping(value = "/delmac")
    public R delmac(@RequestBody JSONObject jsonObject) throws Default200Exception {
        String mac = jsonObject.getString("mac");
        DeviceEntity deviceEntity = deviceService.getByName(mac);
        if (deviceEntity == null) {
            throw new Default200Exception(ErrorConstant.not_found);
        }
        deviceService.removeById(deviceEntity);
        //记录在log表里
        DeviceRegisterLogEntity deviceRegisterLogEntity = new DeviceRegisterLogEntity();
        deviceRegisterLogEntity.setMac(mac);
        deviceRegisterLogEntity.setHotelid(String.valueOf(deviceEntity.getHotelid()));
        deviceRegisterLogEntity.setRoomid(deviceEntity.getRoomname());
        deviceRegisterLogEntity.setType(deviceEntity.getNickname());
        deviceRegisterLogEntity.setCtime(new Date());
        deviceRegisterLogEntity.setNote("删除");
        deviceRegisterLogService.save(deviceRegisterLogEntity);
        return R.ok();
    }



    //修改设备
    @ResponseBody
    @RequiresPermissions(value = {"30"}, logical = Logical.OR)
    @RequestMapping(value = "/editmac")
    public R editmac(@RequestBody DeviceEntity deviceEntity) throws Default200Exception {
        deviceService.updateById(deviceEntity);
        return R.ok();
    }


    //更换设备  只能改表号 不能改表类型 酒店号 房间号 并且记录在log表里
    @ResponseBody
    @RequiresPermissions(value = {"26"}, logical = Logical.OR)
    @RequestMapping(value = "/exchange")
    public R exchange(@RequestBody JSONObject jsonObject) throws Default200Exception {

        String oldmac = jsonObject.getString("oldmac");
        DeviceEntity olddevice = deviceService.getByName(oldmac);
        if (olddevice == null) {
            throw new Default200Exception(ErrorConstant.not_found);
        }
        deviceService.removeById(olddevice);
        //记录在log表里
        DeviceRegisterLogEntity deviceRegisterLogEntity = new DeviceRegisterLogEntity();
        deviceRegisterLogEntity.setMac(olddevice.getName());
        deviceRegisterLogEntity.setHotelid(String.valueOf(olddevice.getHotelid()));
        deviceRegisterLogEntity.setRoomid(olddevice.getRoomname());
        deviceRegisterLogEntity.setType(olddevice.getNickname());
        deviceRegisterLogEntity.setCtime(new Date());
        deviceRegisterLogEntity.setNote("删除-替换操作");
        deviceRegisterLogService.save(deviceRegisterLogEntity);


        //即将替换的设备

        String msg = "替换成功";
        String newmac = jsonObject.getString("newmac");
        DeviceEntity newdevcie = deviceService.getByName(newmac);
        if (newdevcie != null) {
            msg = "您输入的表号已存在，将额外为您删除该表号，进行替换";
            deviceService.removeById(newdevcie);
            //记录在log表里
            deviceRegisterLogEntity.setMac(olddevice.getName());
            deviceRegisterLogEntity.setHotelid(String.valueOf(olddevice.getHotelid()));
            deviceRegisterLogEntity.setRoomid(olddevice.getRoomname());
            deviceRegisterLogEntity.setType(olddevice.getNickname());
            deviceRegisterLogEntity.setCtime(new Date());
            deviceRegisterLogEntity.setNote("额外删除-替换操作");
            deviceRegisterLogService.save(deviceRegisterLogEntity);

        }

        olddevice.setName(newmac);
        olddevice.setCtime(new Date());

        deviceService.save(olddevice);

        //记录在log表里
        deviceRegisterLogEntity.setMac(olddevice.getName());
        deviceRegisterLogEntity.setHotelid(String.valueOf(olddevice.getHotelid()));
        deviceRegisterLogEntity.setRoomid(olddevice.getRoomname());
        deviceRegisterLogEntity.setType(olddevice.getNickname());
        deviceRegisterLogEntity.setCtime(new Date());
        deviceRegisterLogEntity.setNote("添加-替换操作");
        deviceRegisterLogService.save(deviceRegisterLogEntity);
        return R.ok(msg);
    }


}
